package com.amm.gwt.gwtgaeuploader.client;

import com.amm.gwt.gwtgaeuploader.client.event.MyEvent;
import com.amm.gwt.gwtgaeuploader.client.event.MyEventHandler;
import com.amm.gwt.gwtgaeuploader.client.resources.MyImages;
import com.amm.gwt.gwtgaeuploader.client.service.GAEUploadRPC;
import com.amm.gwt.gwtgaeuploader.client.service.GAEUploadRPCAsync;
import com.google.gwt.core.client.GWT;
import com.google.gwt.event.dom.client.ChangeEvent;
import com.google.gwt.event.shared.HandlerRegistration;
import com.google.gwt.event.shared.SimpleEventBus;
import com.google.gwt.uibinder.client.UiBinder;
import com.google.gwt.uibinder.client.UiField;
import com.google.gwt.uibinder.client.UiHandler;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.*;


public class GWTGAEUploaderForm extends Composite {
    interface MyUiBinder extends UiBinder<Widget, GWTGAEUploaderForm> {
    }

    private static MyUiBinder myUiBinder = GWT.create(MyUiBinder.class);
    private static GAEUploadRPCAsync imageRPCAsync = GWT.create(GAEUploadRPC.class);
    private String myAppengineHost = null;
    private Boolean localhost = Boolean.TRUE;

    private SimpleEventBus simpleEventBus = new SimpleEventBus();

    public HandlerRegistration addHandler(MyEventHandler handler) {
        return simpleEventBus.addHandler(MyEvent.TYPE, handler);
    }


    @UiField
    FormPanel formPanel;
    @UiField
    Hidden uploadUrl;
    @UiField
    FileUpload fileUpload;
    @UiField(provided = true)
    Image loading = new Image(MyImages.instance.loading());

    /**
     * Do not use this constructor. It is only for GWT binder to work properly
     * You must provide an appengineHost url
     */
    public GWTGAEUploaderForm() {
        initWidget(myUiBinder.createAndBindUi(this));
    }

    /**
     * @param myAppengineHost Your appengine storage server base url
     */
    public GWTGAEUploaderForm(String myAppengineHost) {
        this();
        this.myAppengineHost = myAppengineHost;
        localhost = (myAppengineHost != null &&
                (myAppengineHost.contains("localhost") || myAppengineHost.contains("127.0.0.1")));
    }

    /**
     * @param myAppengineHost Your appengine storage server base url
     * @param handler         The handler for the serving image url after upload it
     */
    public GWTGAEUploaderForm(String myAppengineHost, MyEventHandler handler) {
        this(myAppengineHost);
        addHandler(handler);
    }

    @UiHandler("formPanel")
    public void onSubmitComplete(FormPanel.SubmitCompleteEvent event) {
        imageRPCAsync.getServingUrl(myAppengineHost, formPanel.getAction(), new AsyncCallback<String>() {
            public void onFailure(Throwable caught) {
                loading.setVisible(false);
                simpleEventBus.fireEvent(new MyEvent(MyEvent.MyEventAction.ERROR, null));
                Window.alert("Error. " + (caught != null ? caught.getMessage() : null));
            }

            public void onSuccess(String result) {
                loading.setVisible(false);
                String url;
                if (localhost)
                    url = "http://localhost:8085" + result;
                else
                    url = result;
                formPanel.reset();
                simpleEventBus.fireEvent(new MyEvent(MyEvent.MyEventAction.IMAGE_SAVED, url));
            }
        });
    }

    @UiHandler("fileUpload")
    public void onChange(ChangeEvent event) {
        if (fileUpload.getFilename() != null) {
            loading.setVisible(true);
            imageRPCAsync.getUploadUrl(myAppengineHost, new AsyncCallback<String>() {
                public void onFailure(Throwable caught) {
                    loading.setVisible(false);
                    simpleEventBus.fireEvent(new MyEvent(MyEvent.MyEventAction.ERROR, null));
                    Window.alert("Error. " + (caught != null ? caught.getMessage() : null));
                }

                public void onSuccess(String result) {
                    if (result == null)
                        onFailure(null);

                    String action;

                    if (localhost)
                        action = "http://localhost:8085" + result;
                    else
                        action = result;

                    uploadUrl.setName("uploadUrl");
                    uploadUrl.setValue(action);

                    fileUpload.setName("myFile");

                    formPanel.setMethod(FormPanel.METHOD_POST);
                    formPanel.setEncoding(FormPanel.ENCODING_MULTIPART);

                    formPanel.setAction(action);

                    formPanel.submit();
                }
            });
        }
    }
}